package com.yolov8.task;


import com.yolov8.model.FrameData;
import com.yolov8.steam.FrameProcessor;
import com.yolov8.steam.VideoPuller;
import com.yolov8.steam.VideoPusher;
import org.bytedeco.opencv.opencv_core.Mat;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;

public class DetectionTask {
    private final String streamUrl;
    private final String modelPath;
    private final String pushUrl;
    private final List<String> classNames;

    private final BlockingQueue<FrameData> pullQueue = new LinkedBlockingQueue<>(100);
    private final BlockingQueue<Mat> pushQueue = new LinkedBlockingQueue<>(100);

    private Thread pullThread;
    private Thread pushThread;

    private VideoPuller puller;
    private VideoPusher pusher;
    private final int NUM_PROCESSORS = 3;
    private final List<Thread> processorThreads = new ArrayList<>();
    private final List<FrameProcessor> processors = new ArrayList<>();


    public DetectionTask(String streamUrl, String modelPath, String pushUrl, List<String> classNames) {
        this.streamUrl = streamUrl;
        this.modelPath = modelPath;
        this.pushUrl = pushUrl;
        this.classNames = classNames;
    }

    public void start() throws Exception {
        puller = new VideoPuller(streamUrl, pullQueue, 3);
        // 创建多个 FrameProcessor 实例并启动线程
        for (int i = 0; i < NUM_PROCESSORS; i++) {
            FrameProcessor processor = new FrameProcessor(modelPath, pullQueue, classNames, pushQueue);
            processors.add(processor);
            Thread thread = new Thread(processor, "Processor-" + i);
            processorThreads.add(thread);
            thread.start();
        }
        pusher = new VideoPusher(pushUrl, pushQueue, 1152, 720); // 分辨率应动态配置

        pullThread = new Thread(puller);
        pushThread = new Thread(pusher);

        pullThread.start();
        pushThread.start();
    }

    public void stop() {
        if (puller != null) puller.stop();
        if (pusher != null) pusher.stop();
        for (FrameProcessor processor : processors) {
            processor.stop();
        }
        for (Thread thread : processorThreads) {
            thread.interrupt();
        }
        pullThread.interrupt();
        pushThread.interrupt();
    }
}
